package com.ruoyi.common.core.domain;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * Treeselect树结构实体类
 * 
 * @author ruoyi
 */
public class TreeSelect implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 节点ID */
    private String id;

    /** 节点名称 */
    private String label;

    /** 子节点 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<TreeSelect> children;
    public TreeSelect(String id,String label)
    {
        this.id=id;
        this.label=label;
    }

    public static <T> List<T> buildDataTree(List<T> dataList, Function<T,Object> idField,Function<T,Object> pidField,Function<T,List<T>> getChilds){
        Map<String,T> treeMap=new HashMap<>();
        List<T> treeList=new ArrayList<>();
        for(T data:dataList){
            Object key=idField.apply(data);
            if(key==null){
                continue;
            }
            treeMap.put(key.toString(),data);
        }
        for(T data:dataList){
            Object key=idField.apply(data);
            if(key==null){
                continue;
            }
            T t=treeMap.get(key.toString());
            if(t==null){
                continue;
            }
            Object pid=pidField.apply(data);
            if(pid==null){
                treeList.add(t);
                continue;
            }
            T p=treeMap.get(pid.toString());
            if(p==null){
                treeList.add(t);
            }else{
                getChilds.apply(p).add(t);
            }
        }
        treeMap.clear();
        return treeList;
    }

    public static <T> List<TreeSelect> buildTree(List<T> dataList, Function<T,Object> idField,Function<T,Object> pidField,Function<T,Object> valueField)
    {
        Map<String,TreeSelect> treeMap=new HashMap<>();
        List<TreeSelect> treeList=new ArrayList<>();
        for(T data:dataList){
            Object key=idField.apply(data);
            Object value=valueField.apply(data);
            if(key==null || value==null){
                continue;
            }
            TreeSelect t=new TreeSelect(key.toString(),value.toString());
            treeMap.put(t.getId(),t);
        }
        for(T data:dataList){
            Object key=idField.apply(data);
            if(key==null){
                continue;
            }
            TreeSelect t=treeMap.get(key.toString());
            if(t==null){
                continue;
            }
            Object pid=pidField.apply(data);
            if(pid==null){
                treeList.add(t);
                continue;
            }
            TreeSelect p=treeMap.get(pid.toString());
            if(p==null){
                treeList.add(t);
            }else{
                p.add(t);
            }
        }
        treeMap.clear();
        return treeList;
    }

    private void add(TreeSelect child){
        if(children==null){
            children=new ArrayList<>();
        }
        children.add(child);
    }

    public String getId()
    {
        return id;
    }

    public void setId(String id)
    {
        this.id = id;
    }

    public String getLabel()
    {
        return label;
    }

    public void setLabel(String label)
    {
        this.label = label;
    }

    public List<TreeSelect> getChildren()
    {
        return children;
    }

    public void setChildren(List<TreeSelect> children)
    {
        this.children = children;
    }
}
